package net.kansun.poc;

import java.util.ArrayList;
import java.util.List;

/**
 * This is a demo of the classical multithreading issue, the consumer-producer pattern.
 */
public class ConsumerProducerDemoWithoutBlockingQueue {

   public static void main(String[] args) {

      List<String> resources = new ArrayList<String>();

      Thread consumerThread = new Thread(new Consumer(resources), "Customer");
      Thread producerThread = new Thread(new Producer(resources), "Producer");

      consumerThread.start();
      producerThread.start();
   }


static class Consumer implements Runnable {

   private final List<String> resources;

   public Consumer(List<String> resources) {
      this.resources = resources;
   }

   @Override
   public void run() {

      while (true) {
         while (resources.isEmpty()) {

            synchronized (resources) {

               try {
                  resources.wait();
               } catch (InterruptedException e) {
               }
            }

         }

         synchronized (resources) {

            if (resources != null && !resources.isEmpty()) {

                  String s = resources.get(0);
                  System.out.println(Thread.currentThread().getName() + ": consumed resource " + s);
                  resources.remove(s);
                  resources.notifyAll();
            }

         }

         try {
            Thread.sleep(50);
         } catch (InterruptedException e) {
         }
      }

   }
}

static class Producer implements Runnable {

   private final List<String> resources;

   public Producer(List<String> resources) {

      this.resources = resources;
   }

   @Override
   public void run() {

      while (true) {
         while (!resources.isEmpty()) {

            synchronized (resources) {
               try {
                  resources.wait();
               } catch (InterruptedException e) {
               }
            }
         }

         synchronized (resources) {
            String s = String.valueOf(System.currentTimeMillis());
            System.out.println(Thread.currentThread().getName() + ": produced resource " + s);
            resources.add(s);
            resources.notifyAll();
         }
      }

   }
}
}
